# -*- coding: utf-8 -*-
import logging
import threading
import typing
import queue

import spider_logging

logger = spider_logging.get_logger(__name__)


def submit(task: typing.Callable, max_worker_count: int = None):
    """向线程池中提交一个新任务，如果线程数量未达到max_worker_count，启动一个新线程立即执行。
    否则等待空闲线程执行。
    """
    active_worker_count = len(SpiderThread.worker_pool)
    if active_worker_count < max_worker_count:
        t = SpiderThread(task, f"SpiderThread-{active_worker_count}")
        SpiderThread.worker_pool.append(t)
    else:
        SpiderThread.task_pool.put(task)


def all_idle():
    """线程池中所有线程是否全部idle。

    Returns:
        线程池中所有线程全部idle时，返回True。
    """

    return all(not t.is_crawling for t in SpiderThread.worker_pool)


def pending_task_count():
    """还在等待执行的任务数。"""
    return SpiderThread.task_pool.qsize()


def abort():
    for t in SpiderThread.worker_pool:
        t.abort = True

    SpiderThread.worker_pool = []


class SpiderThread(threading.Thread):
    lock = threading.Lock()
    worker_pool = []
    task_pool = queue.Queue()

    def __init__(self, task: typing.Callable = None, name: str = None):
        super().__init__(name=name)

        self.task = task
        self.is_crawling = False
        self.abort = False
        self.start()

    def run(self):
        if self.task:
            self.is_crawling = True

            try:
                self.task()
            except Exception as e:
                logger.log(logging.DEBUG, f"error={e}")

            self.is_crawling = False

        while True:
            if self.abort:
                logger.log(logging.DEBUG, f"线程正在退出: name={self.name}")
                break

            try:
                task = SpiderThread.task_pool.get_nowait()
                self.is_crawling = True
                task()
            except queue.Empty:
                pass
            except Exception as e:
                logger.log(logging.DEBUG, f"error={e}")

            self.is_crawling = False
